`timescale 1ns / 1ps
// `default_nettype none
`include "InstrHeader.h"

//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    21:43:26 06/26/2019 
// Design Name: 
// Module Name:    TopLevel 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module TopLevel(
	input	wire	clk_50M,
	input	wire	Clk,
	input	wire	Clr,
	inout	wire	[31:0]	base_ram_data,  //BaseRAM数据，低8位与CPLD串口控制器共享
    output	wire	[19:0]	base_ram_addr, //BaseRAM地址
    output	wire	[3:0]	base_ram_be_n,  //BaseRAM字节使能，低有效。如果不使用字节使能，请保持为0
    output	wire	base_ram_ce_n,       //BaseRAM片选，低有效
    output	wire	base_ram_oe_n,       //BaseRAM读使能，低有效
    output	wire	base_ram_we_n,      //BaseRAM写使能，低有效
	 //ExtRAM信号
    inout	wire	[31:0]	ext_ram_data,  //ExtRAM数据
    output	wire	[19:0]	ext_ram_addr, //ExtRAM地址
    output	wire	[3:0]	ext_ram_be_n,  //ExtRAM字节使能，低有效。如果不使用字节使能，请保持为0
    output	wire	ext_ram_ce_n,       //ExtRAM片选，低有效
    output	wire	ext_ram_oe_n,       //ExtRAM读使能，低有效
    output	wire	ext_ram_we_n,       //ExtRAM写使能，低有效

	output	wire	txd,  //直连串口发送端
    input	wire	rxd  //直连串口接收端
    );
	
	wire [31:0]	D_Instr,E_Instr,M_Instr;
	wire I_sram_busy;
	wire D_stall_Pass;
	wire [31:0] D_NewPC_Pass,I_PC_Pass;
	
	wire [31:0] I_PC,I_Instr;
	wire [31:0] I_sram_addr;
	wire [31:0]	I_sram_data;
	InstrFetchState InstrFetchState(.Clk(Clk),
									.Clr(Clr),
									.D_stall_Pass(D_stall_Pass),
									.D_NewPC_Pass(D_NewPC_Pass),
									.I_PC(I_PC),
									.I_PC_Pass(I_PC_Pass),
									.I_Instr(I_Instr),
									.I_sram_addr(I_sram_addr),
									.I_sram_data(I_sram_data),
									.I_sram_busy(I_sram_busy));
	

	wire M_WriteRegEnable;
	wire [4:0] M_RegWriteId;
	wire [31:0] M_RegWriteData;
	wire [4:0] D_RsID,D_RtID;
	wire [31:0] D_RsData,D_RtData;
	wire [4:0] D_Shamt;
	wire [15:0] D_Imm16;
	wire [`InstrBusWidth] D_InstrBus;
	wire [31:0]	D_PC,M_PC;
	wire [3:0] E_T,D_T;
	wire E_WriteRegEnable,D_WriteRegEnable;
	wire [4:0] E_RegId,D_RegId;
	wire [31:0] E_Data;
	wire E_XALU_Busy;
	wire [4:0] M_RegId;
	wire [31:0] M_Data;
	DecodeState DecodeState(.Clk(Clk),.Clr(Clr),.W_WriteRegEnable(M_WriteRegEnable),.W_RegWriteId(M_RegId),.W_RegWriteData(M_Data),.I_PC_Pass(I_PC_Pass),.I_PC(I_PC),.I_MipsInstr(I_Instr),.W_PC(M_PC),
							.D_NewPC_Pass(D_NewPC_Pass),.D_PC(D_PC),.D_RsID(D_RsID),.D_RtID(D_RtID),.D_RsData(D_RsData),.D_RtData(D_RtData),.D_Shamt(D_Shamt),.D_Imm16(D_Imm16),.D_InstrBus(D_InstrBus),
							.E_T(E_T),.E_WriteRegEnable(E_WriteRegEnable),.E_RegId(E_RegId),.E_Data(E_Data),.D_T(D_T),.D_WriteRegEnable(D_WriteRegEnable),.D_RegId(D_RegId),.D_stall_Pass(D_stall_Pass),
							.E_XALU_Busy(E_XALU_Busy),.I_sram_busy(I_sram_busy),.D_Instr(D_Instr));
	


	wire [31:0] E_PC;
	wire [31:0] E_WriteMemData;
	wire [31:0]	E_MemWriteData_MFed;
	wire [4:0] E_RtID;

	wire [3:0] E_MemBitEnable;
	wire E_MemReadEnable;
	wire E_MemWriteEnable;
	wire [4:0] E_ExtType;
	// output reg	[3:0]   E_MemBitEnable,
	// output reg	E_MemReadEnable,
    // output reg	E_MemWriteEnable,
	// output reg	[4:0]   E_ExtType,
	ExecuteSdate ExecuteSdate(.Clk(Clk),.Clr(Clr),.D_PC(D_PC),.D_RsID(D_RsID),.D_RtID(D_RtID),.D_RsData(D_RsData),.D_RtData(D_RtData),.D_Shamt(D_Shamt),.D_Imm16(D_Imm16),.D_InstrBus(D_InstrBus),.D_T(D_T),.D_WriteRegEnable(D_WriteRegEnable),
								.D_RegId(D_RegId),.M_WriteRegEnable(M_WriteRegEnable),.M_RegId(M_RegId),.M_Data(M_Data),.E_PC(E_PC),.E_WriteMemData(E_WriteMemData),.E_RtID(E_RtID),
								.E_T(E_T),.E_WriteRegEnable(E_WriteRegEnable),.E_RegId(E_RegId),.E_Data(E_Data),.E_ExtType(E_ExtType),
								.E_MemBitEnable(E_MemBitEnable),.E_MemReadEnable(E_MemReadEnable),.E_MemWriteEnable(E_MemWriteEnable),
								.E_XALU_Busy(E_XALU_Busy),.D_Instr(D_Instr),.E_Instr(E_Instr));

	wire	[31:0]	E_Mem_read_data;
	MemState MemState(	.Clk(Clk),
						.Clr(Clr),
						.E_PC(E_PC),
						.E_Instr(E_Instr),
						.E_MemWriteData(E_WriteMemData),
						.E_RtID(E_RtID),
						.E_Data(E_Data),
						.E_WriteRegEnable(E_WriteRegEnable),
						.E_RegId(E_RegId),
						.M_WriteRegEnable(M_WriteRegEnable),
						.M_RegId(M_RegId),
						.M_Data(M_Data),
						.M_PC(M_PC),
						.E_Mem_read_data(E_Mem_read_data),
						// .E_MemBitEnable(E_MemBitEnable),
						.E_MemReadEnable(E_MemReadEnable),
						// .E_MemWriteEnable(E_MemWriteEnable),
						.E_ExtType(E_ExtType),

						.E_MemWriteData_MFed(E_MemWriteData_MFed)
						);

	wire	[31:0]  E_Mem_addr = E_Data;
	Bridge Bridge(	.clk_50M(clk_50M),
					.clk(Clk),
					.clr(Clr),
					.base_ram_data(base_ram_data),
					.base_ram_addr(base_ram_addr),
					.base_ram_be_n(base_ram_be_n),
					.base_ram_ce_n(base_ram_ce_n),
					.base_ram_oe_n(base_ram_oe_n),
					.base_ram_we_n(base_ram_we_n),
					
					.ext_ram_data(ext_ram_data),
					.ext_ram_addr(ext_ram_addr),
					.ext_ram_be_n(ext_ram_be_n),
					.ext_ram_ce_n(ext_ram_ce_n),
					.ext_ram_oe_n(ext_ram_oe_n),
					.ext_ram_we_n(ext_ram_we_n),

					.I_sram_addr(I_sram_addr),
					.I_sram_data(I_sram_data),
					.I_sram_busy(I_sram_busy),
					
					.E_Mem_addr(E_Mem_addr),
					.E_Mem_write_data(E_MemWriteData_MFed),
					.E_Mem_read_data(E_Mem_read_data),
					.E_MemBitEnable(E_MemBitEnable),
					.E_MemReadEnable(E_MemReadEnable),
					.E_MemWriteEnable(E_MemWriteEnable),
					.rxd(rxd),
					.txd(txd)
					);
									
endmodule
